/* ----------------------------------------------------------------------------

	pax.plugin.widget.spell.js Copyright (C) 2007, 2008 Mikkel Bergmann, Pointful

	Licence
	-------
	
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

	See lgpl.txt for licence details

---------------------------------------------------------------------------- */
/*
	Script: pax.plugin.widget.spell
		This is a spell checking widget plugin for PAX
		
	Author:
		Mikkel Bergmann, <http://www.pointful.com>

*/

var pax = pax || {};
pax.plugin = pax.plugin || {};
pax.plugin.widget = pax.plugin.widget || {};
pax.plugin.widget.spell = pax.plugin.widget.spell || {};
pax.plugin.widget.spell.url = '/anders2/lib/control/test/test_aspell_service.php';		//	Default for testing

pax.plugin.widget.spell.init = function( displayField, args ) {

	displayField.replacedTextList = {};
	
	//	This should setup the button to check spelling
	args = ( typeof( args ) != 'undefined' )? args: {};	
	args.ignoreTags = (args.ignoreTags)? args.ignoreTags: false;	//	Parameter to send to the server side, to indicate that it should strip HTML before spell checking
	if( args.url )pax.plugin.widget.spell.url = args.url;
	
	if( ! args.button ) {
		//	TODO: Create a button
	} else {
		var startCheck = 'Check spelling';
		var duringCheck = 'Please wait...';
		var finishCheck = 'Finish checking';
		var checkSpelling = function() {
			//	Completed check, so set everything back
			if( this.innerHTML == finishCheck ) {
				this.innerHTML = startCheck;
				for( var change in displayField.replacedTextList ) {
					displayField.checkText = displayField.checkText.split( change ).join( displayField.replacedTextList[change] );
				}				
				displayField.value = displayField.checkText;
				
				pax.box.hide( pax.$('spell_check_' + displayField.name) );	//	Remove floating div
				displayField.replacedTextList = {};						//	Remove / reset displayField.replacedTextList
				displayField.checkText = '';							//	Remove / reset displayField.checkText
				//	if( args.auto )args.auto.disabled = false;				//	Re-enable autocorrect
			} else {	//	Start spell check
				this.innerHTML = duringCheck;
				this.disabled = true;
				//	if( args.auto )args.auto.disabled = true;
				pax.plugin.widget.spell.display( displayField, args, function() {
					args.button.innerHTML = finishCheck;
					args.button.disabled = false;
				} );
			}
		};
		pax.event.bind( args.button, 'click', checkSpelling );
		args.button.innerHTML = startCheck;
	}
	
	//	TODO: Improve the autocomplete to NOT re-download, if we've in spell check mode already
	if( args.auto ) {
		pax.event.bind( args.auto, 'click', function() {
			if( args.button )args.button.disabled = true;				//	Disable spell check
			pax.plugin.widget.spell.autoCorrect( displayField, args, function() {
				if( args.button ) {
					args.button.disabled = false;			//	Re-enable spell check
					args.button.innerHTML = startCheck;
				}
			} );
		} );
	}
	
};


pax.plugin.widget.spell.autoCorrect = function( displayField, args, callback ) {
	//	Create a box, and overlay it on top of the textarea
	var pos = pax.util.getPosition( displayField );
	var div = pax.box.show( 'spell_check_' + displayField.name, '<span id="paxSpellcheckStatusBox"></span>Auto correcting spelling, please wait...', 'paxSpellCheckArea', pos.x, pos.y );
	pax.util.setPosition( div, { x: pos.x, y: pos.y, width: pos.width - 16, height: pos.height - 16 } );
	
	//	Run the ajax request, and highlight misspelled words
	//	Note: we use POST, as the size of a GET will probably be too small for the text in a medium sized textarea
	pax.post( pax.plugin.widget.spell.url, { auto: true, text: displayField.value, ignoreTags: args.ignoreTags }, function( xml, txt, url ) {
		//	This function should iterate through the text, and add an anchor with class name: paxSpellCheckIncorrect
		var text = displayField.value;
		var result = pax.unJSON( txt );
		result = result['result'];
		
		//	As this is auto correct, we simply replace each word with the first result.
		for( var word in result ) {
			text = text.split( word ).join( result[word] );
		}
		
		displayField.value = text;
		
		pax.box.hide( div );
		
		if( pax.util.getType( callback ) == 'function' )callback();
		
	}, 'Auto correct checking spelling', pax.$('paxSpellcheckStatusBox') );
};


pax.plugin.widget.spell.display = function( displayField, args, callback ) {
	//	Create a box, and overlay it on top of the textarea
	var pos = pax.util.getPosition( displayField );
	var div = pax.box.show( 'spell_check_' + displayField.name, '<span id="paxSpellcheckStatusBox"></span>Checking spelling, please wait...', 'paxSpellCheckArea', pos.x, pos.y );
	pax.util.setPosition( div, { x: pos.x, y: pos.y, width: pos.width - 16, height: pos.height - 16 } );
	div.style.overflow = 'auto';
	
	//	Run the ajax request, and highlight misspelled words	
	//	Note: we use POST, as the size of a GET will probably be too small for the text in a medium sized textarea
	pax.post( pax.plugin.widget.spell.url, { text: displayField.value, ignoreTags: args.ignoreTags }, function( xml, txt, url ) {
		//	This function should iterate through the text, and add an anchor with class name: paxSpellCheckIncorrect
		var text = displayField.value;
		var result = pax.unJSON( txt );
		result = result['result'];
		
		//	Add an anchor around each word, plus a unique ID
		var count = 0;
		for( var word in result ) {
			text = text.split( word );
			var replacedText = '';
			for( var i = 0; i < text.length; i++ ) {
				var myID = 'paxSpellCheckIncorrect_' + count;
				if( i < text.length - 1 ) {
					var changeLink = '<a class="paxSpellCheckIncorrect" id="' + myID + '">' + word + '</a>';
					replacedText += text[i] + changeLink;
					displayField.replacedTextList[changeLink] = word;
				}
				else replacedText += text[i];
				count += 1;
			}
			count += 1;
			text = replacedText;
		}
		
		div.innerHTML = text;
		displayField.checkText = text;
		
		//	Event that displays a box which you can use to choose a word.
		var changeWord = function( e ) {
			var dims = pax.util.getPosition( this );
			var words = pax.util.copyObj( result[this.innerHTML] );		//	We must copy the object, so we don't change the original.
			
			//	Add a function to select a word
			/*	INTERESTING IE7 *bug?*: if no href in anchor tag, hover DOES NOT work...	*/
			for( var w in words ) {
				words[w] = '<a href="javascript:void(0);" rel="' + this.id + '">' + words[w] + '</a>';
			}
			
			var message = words.join('');
			var myBox = pax.box.show( "paxSCBox", message, 'paxSpellCheckBox', dims.x, dims.y + dims.height + 8 );
			
			//	Assign a function to set the selected word, attach a click handeler to myBox, and look at which word was selected.
			pax.event.bind( myBox, 'click', function( e ) {
				var clickTarget = e.target || window.event.srcElement;
				var correctWord = clickTarget.innerHTML;
				
				for( var change in displayField.replacedTextList ) {
					if( change.indexOf( '"' + pax.$( clickTarget.rel ).id + '"' ) != -1 ) {
						displayField.replacedTextList[change] = correctWord;
					}
				}
				
				pax.$( clickTarget.rel ).innerHTML = correctWord;
				
				pax.util.removeClassName( pax.$( clickTarget.rel ), 'paxSpellCheckIncorrect' );
				//	Unbind click events, and destroy wordListBox.
				pax.box.hide( this );
				pax.event.unbind( pax.$( clickTarget.rel ) );
			} );
			
			//	Stop the click event from propegating, so the event below doesn't immediately hide the box.
			pax.event.preventpropagate(e);
			//	Add click event on body that hides the box
			pax.event.bind( document.body, 'click', function( e ) {
				var target = e.target || window.event.srcElement;
				if( target != myBox )pax.box.hide( myBox );
			} );
		};
		
		var wordList = pax.util.getElementsByClassName( div, 'a', 'paxSpellCheckIncorrect' );
		
		for( var i in wordList ) {
			var word = wordList[i];
			pax.event.bind( word, 'click', changeWord );
		}
		
		if( pax.util.getType( callback ) == 'function' )callback();
		
	}, 'Checking spelling', pax.$('paxSpellcheckStatusBox') );
};
